import {
  registerDecorator,
  ValidationOptions,
  ValidationArguments,
} from 'class-validator';

/**
 * 自定义验证装饰器
 * 基于 class-validator 实现
 * 对应 Java: 自定义验证注解
 */

/**
 * 验证手机号
 */
export function IsPhoneNumber(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isPhoneNumber',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          if (typeof value !== 'string') return false;
          const phoneRegex = /^1[3-9]\d{9}$/;
          return phoneRegex.test(value);
        },
        defaultMessage(args: ValidationArguments) {
          return '手机号格式不正确';
        },
      },
    });
  };
}

/**
 * 验证邮箱
 */
export function IsEmail(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isEmail',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          if (typeof value !== 'string') return false;
          const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
          return emailRegex.test(value);
        },
        defaultMessage(args: ValidationArguments) {
          return '邮箱格式不正确';
        },
      },
    });
  };
}

/**
 * 验证密码强度
 */
export function IsStrongPassword(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isStrongPassword',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          if (typeof value !== 'string') return false;
          // 至少8位，包含大小写字母、数字和特殊字符
          const strongPasswordRegex =
            /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
          return strongPasswordRegex.test(value);
        },
        defaultMessage(args: ValidationArguments) {
          return '密码必须至少8位，包含大小写字母、数字和特殊字符';
        },
      },
    });
  };
}

/**
 * 验证用户名
 */
export function IsUsername(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isUsername',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          if (typeof value !== 'string') return false;
          // 3-20位，只能包含字母、数字、下划线
          const usernameRegex = /^[a-zA-Z0-9_]{3,20}$/;
          return usernameRegex.test(value);
        },
        defaultMessage(args: ValidationArguments) {
          return '用户名必须是3-20位字母、数字或下划线';
        },
      },
    });
  };
}

/**
 * 验证文件扩展名
 */
export function IsFileExtension(
  allowedExtensions: string[],
  validationOptions?: ValidationOptions,
) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isFileExtension',
      target: object.constructor,
      propertyName: propertyName,
      constraints: [allowedExtensions],
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          if (typeof value !== 'string') return false;
          const [allowedExtensions] = args.constraints;
          const extension = value.split('.').pop()?.toLowerCase();
          return allowedExtensions.includes(extension);
        },
        defaultMessage(args: ValidationArguments) {
          const [allowedExtensions] = args.constraints;
          return `文件扩展名必须是: ${allowedExtensions.join(', ')}`;
        },
      },
    });
  };
}

/**
 * 验证日期范围
 */
export function IsDateRange(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'isDateRange',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          if (!value || typeof value !== 'object') return false;
          if (!value.startDate || !value.endDate) return false;
          const startDate = new Date(value.startDate);
          const endDate = new Date(value.endDate);
          return startDate <= endDate;
        },
        defaultMessage(args: ValidationArguments) {
          return '开始日期必须小于等于结束日期';
        },
      },
    });
  };
}
